package com.yomob.kylin.support.joptsimple.util;

import com.yomob.kylin.facility.Consts;
import com.yomob.kylin.support.Messages;
import joptsimple.ValueConversionException;
import joptsimple.ValueConverter;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class LocalDateConverter implements ValueConverter<LocalDate> {
    private final String pattern;
    private final DateTimeFormatter formatter;

    /**
     * Creates a converter that uses the given date formatter/parser.
     *
     * @param pattern the formatter pattern to use
     * @throws NullPointerException if {@code formatter} is {@code null}
     */
    private LocalDateConverter(String pattern) {
        if (pattern == null) {
            throw new NullPointerException("illegal null formatter pattern");
        }
        this.pattern = pattern;
        this.formatter = DateTimeFormatter.ofPattern(pattern);
    }

    /**
     * Creates a converter that uses a {@link DateTimeFormatter} with the given date pattern.
     *
     * @param pattern expected date pattern
     * @return the new converter
     * @throws NullPointerException     if {@code pattern} is {@code null}
     * @throws IllegalArgumentException if {@code pattern} is invalid
     */
    public static LocalDateConverter ofPattern(String pattern) {
        return new LocalDateConverter(pattern);
    }

    @Override
    public LocalDate convert(String value) {
        try {
            return LocalDate.parse(value, formatter);
        } catch (DateTimeParseException e) {
            String message = message(Consts.ExceptionMessageKey.VALUE_NO_MATCH_PATTERN, value, valuePattern());
            throw new ValueConversionException(message);
        }

    }

    @Override
    public Class<LocalDate> valueType() {
        return LocalDate.class;
    }

    @Override
    public String valuePattern() {
        return pattern;
    }

    private String message(String key, Object... values) {
        return Messages.message(Consts.Bundle.EXCEPTION_MESSAGES,
                LocalDateConverter.class,
                key,
                values);
    }

}
